//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Specialized;

namespace CommunityServer.Components
{
	/// <summary>
	/// Provides base access to managing Sections
	/// </summary>
	public class Sections
	{
		private Sections()
		{
		}

		/// <summary>
		/// Adds a new Sections
		/// </summary>
		public static int AddSection (Section section) 
		{
			CSEvents.BeforeSection(section,ObjectState.Create,section.ApplicationType);

			section.SectionID = CreateUpdateDeleteSection(section, DataProviderAction.Create);
            EventLogs.Write(string.Format("Section {0} ({1}) in application {2} was created",section.Name,section.SectionID,section.ApplicationType),"Data", 204,EventType.Information, CSContext.Current.SettingsID);
			CSEvents.AfterSection(section,ObjectState.Create,section.ApplicationType);
			
			return section.SectionID;
		}

		/// <summary>
		/// Updates an existing Section
		/// </summary>
		/// <param name="section"></param>
		/// <returns></returns>
		public static int UpdateSection (Section section) 
		{
			CSEvents.BeforeSection(section,ObjectState.Update,section.ApplicationType);

			CreateUpdateDeleteSection(section, DataProviderAction.Update);
			
			CSEvents.AfterSection(section,ObjectState.Update,section.ApplicationType);
			
			return section.SectionID;       
		}

		/// <summary>
		/// Deletes an existing Section
		/// </summary>
		/// <param name="section"></param>
		public static void DeleteSection (Section section) 
		{
			CSEvents.BeforeSection(section,ObjectState.Delete,section.ApplicationType);

			// Delete the post categories
			foreach(PostCategory pc in PostCategories.GetCategories(section.SectionID,false,true,-1,true))
				PostCategories.DeleteCategory(pc.CategoryID, section.SectionID);

			CreateUpdateDeleteSection(section, DataProviderAction.Delete);

            EventLogs.Write(string.Format("Section {0}({1}) was deleted",section.Name,section.SectionID),"Data",208,EventType.Information,section.SettingsID);

			CSEvents.AfterSection(section,ObjectState.Delete,section.ApplicationType);
		}



		#region Filters

		/// <summary>
		/// Filters a list of sections based on the specified permissions for the CURRENT user.
		/// </summary>
		/// <param name="sections">An ArrayList of the Sections to filter</param>
		/// <param name="permissions">The mask of the permissions to filter on</param>
		/// <returns>ArrayList</returns>
		public static ArrayList FilterByAccessControl(ArrayList sections, Permission permissions)
		{
			User u = CSContext.Current.User;
			return FilterByAccessControl(sections,permissions,u);
		}

		/// <summary>
		/// Filters by the specified user
		/// </summary>
		public static ArrayList FilterByAccessControl(ArrayList sections, Permission permissions, User userToFilterBy)
		{
			ArrayList filteredList = new ArrayList();
			foreach(Section s in sections)
			{
				if(Permissions.ValidatePermissions(s, permissions,userToFilterBy)) 
				{
					filteredList.Add(s);
				}
			}
			return filteredList;
		}


		/// <summary>
		/// Filters by IsCommunityAggregated
		/// </summary>
		public static ArrayList FilterByAggregated(ArrayList sections, bool isCommunityAggregated)
		{
			ArrayList filteredList = new ArrayList();
			foreach(Section s in sections)
			{
				if(s.IsCommunityAggregated == isCommunityAggregated) 
					filteredList.Add(s);
			}
			return filteredList;
		}

		public static Hashtable FilterByLanguage(Hashtable sections, CSContext context)
		{
			if (!context.SiteSettings.EnableSectionLocalization || context.User.FilterLanguageKeysToExclude.Length == 0)
				return sections;

			Hashtable filteredSections = new Hashtable();
			ArrayList filterLanguageKeys = new ArrayList(context.User.FilterLanguageKeysToExclude);
			Section s;
			foreach(object key in sections.Keys)
			{
				s = (Section) sections[key];
				if (Globals.IsNullorEmpty(s.DefaultLanguage) || !filterLanguageKeys.Contains(s.DefaultLanguage))
					filteredSections.Add(key, s);
			}

			return filteredSections;;
		}

		public static ArrayList FilterByLanguage(ArrayList sections, CSContext context)
		{
			if (!context.SiteSettings.EnableSectionLocalization || context.User.FilterLanguageKeysToExclude.Length == 0)
				return sections;

			ArrayList filteredSections = new ArrayList();
			ArrayList filterLanguageKeys = new ArrayList(context.User.FilterLanguageKeysToExclude);
			foreach(Section s in sections)
			{
				if (Globals.IsNullorEmpty(s.DefaultLanguage) || !filterLanguageKeys.Contains(s.DefaultLanguage))
					filteredSections.Add(s);
			}

			return filteredSections;;
		}

		#endregion

		public static Section GetRandomSection(ArrayList sections)
		{
			if(sections == null || sections.Count == 0)
				return null;
			if(sections.Count == 1)
				return sections[0] as Section;

			Random rnd = new Random();
			int r = rnd.Next(0,sections.Count);

			return sections[r] as Section;
		}

		private static int CreateUpdateDeleteSection (Section section, DataProviderAction action) 
		{
			// Create Instance of the CommonDataProvider
			CommonDataProvider dp = CommonDataProvider.Instance();

			return dp.CreateUpdateDeleteSection(section, action);
		}

		public static void MoveOrReOrder(int groupID, int sectionID, int index)
		{
			CommonDataProvider dp = CommonDataProvider.Instance();
			dp.SectionMoveOrReOrder(groupID,sectionID,index);
		}

		// *********************************************************************
		//  GetReadSections
		//
		/// <summary>
		/// Returns an list of sections with details on what the user has read
		/// </summary>
		// ***********************************************************************/
		public static HybridDictionary GetSectionsRead(int userID, bool flush) 
		{

			string cacheKey = "sections-read-" + userID.ToString();

			HybridDictionary d = CSCache.Get(cacheKey) as HybridDictionary;

			if (d == null || flush) 
			{

				// Create Instance of the IDataProvider
				CommonDataProvider dp = CommonDataProvider.Instance();

				d = dp.GetSectionsRead(userID);		
			}

			CSCache.MicroInsert(cacheKey, d, 2);

			return d;
		}

		public static void RemoveSectionTracking(int sectionID, int userID) 
		{
			// Create Instance of the CommonDataProvider
			CommonDataProvider dp = CommonDataProvider.Instance();
			dp.RemoveSectionTracking( sectionID, userID );
		}

		#region Auto Naming

		/// <summary>
		/// Searches the list for the next available name based on the pattern string
		/// </summary>
		public static string NextSectionName(ArrayList sections , string baseName)
		{
			string newname = baseName;
			if(!HasSection(sections, newname))
				return newname;
			
			int i = 2;
			newname = string.Concat(baseName, " ({0})");
			while(HasSection(sections, string.Format(newname,i)))
				i++;

			return string.Format(newname,i);
		}

		/// <summary>
		/// Checks to see if a category with that name already exists in the list
		/// </summary>
		public static bool HasSection(ArrayList sections, string name)
		{
			foreach(Section section in sections)
				if(section.Name.ToLower() == name.ToLower())
					return true;

		
			string formattedAppKey = null;
			Globals.ValidateApplicationKey(name,out formattedAppKey);

			foreach(Section section in sections)
				if(string.Compare(section.ApplicationKey, formattedAppKey, true) == 0)
					return true;

			return false;
		}

		#endregion
	}
}
